package edu.northwestern.cbits.purple.notifier;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import android.appwidget.AppWidgetProvider;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.net.Uri;
import android.util.DisplayMetrics;
public abstract class PurpleWidgetProvider extends AppWidgetProvider
{
public void onDeleted (Context context, int[] appWidgetIds)
{
}
public static String createHash(String string)
{
if (string == null)
return null;
String hash = null;
try
{
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] digest = md.digest(string.getBytes("UTF-8"));
hash = (new BigInteger(1, digest)).toString(16);
while (hash.length() < 32)
{
hash = "0" + hash;
}
}
catch (NoSuchAlgorithmException e)
{
e.printStackTrace();
}
catch (UnsupportedEncodingException e)
{
e.printStackTrace();
}
return hash;
}
private static InputStream inputStreamForUri(Context context, Uri imageUri)
{
String hash = PurpleWidgetProvider.createHash(imageUri.toString());
File folder = context.getCacheDir();
File cacheFile = new File(folder, hash);
try
{
return new FileInputStream(cacheFile);
}
catch (FileNotFoundException e)
{
try
{
HttpURLConnection conn = (HttpURLConnection) (new URL(imageUri.toString())).openConnection();
InputStream input = conn.getInputStream();
FileOutputStream fout = new FileOutputStream(cacheFile);
byte[] buffer = new byte[4096];
int read = 0;
while ((read = input.read(buffer, 0, buffer.length)) != -1)
{
fout.write(buffer, 0, read);
}
input.close();
fout.close();
return PurpleWidgetProvider.inputStreamForUri(context, imageUri);
}
catch (MalformedURLException e1)
{
e1.printStackTrace();
}
catch (IOException e1)
{
e1.printStackTrace();
}
e.printStackTrace();
}
return null;
}
protected static Bitmap bitmapForUri(Context context, Uri imageUri) throws IOException
{
if (imageUri == null)
{
Bitmap b = BitmapFactory.decodeResource(context.getResources(), R.drawable.ic_launcher);
return b;
}
InputStream input = PurpleWidgetProvider.inputStreamForUri(context, imageUri);
if (input == null)
return null;
BitmapFactory.Options onlyBoundsOptions = new BitmapFactory.Options();
onlyBoundsOptions.inJustDecodeBounds = true;
onlyBoundsOptions.inDither=true;//optional
onlyBoundsOptions.inPreferredConfig=Bitmap.Config.ARGB_8888;//optional
BitmapFactory.decodeStream(input, null, onlyBoundsOptions);
input.close();
if ((onlyBoundsOptions.outWidth == -1) || (onlyBoundsOptions.outHeight == -1))
return null;
int originalSize = (onlyBoundsOptions.outHeight > onlyBoundsOptions.outWidth) ? onlyBoundsOptions.outHeight : onlyBoundsOptions.outWidth;
double ratio = (originalSize > 144) ? (originalSize / 144) : 1.0;
BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();
bitmapOptions.inSampleSize = PurpleWidgetProvider.getPowerOfTwoForSampleRatio(ratio);
bitmapOptions.inDither=true;
bitmapOptions.inPreferredConfig=Bitmap.Config.ARGB_8888;//optional
input = PurpleWidgetProvider.inputStreamForUri(context, imageUri);
Bitmap bitmap = BitmapFactory.decodeStream(input, null, bitmapOptions);
input.close();
return bitmap;
}
// http://stackoverflow.com/questions/3879992/get-bitmap-from-an-uri-android
private static int getPowerOfTwoForSampleRatio(double ratio)
{
int k = Integer.highestOneBit((int)Math.floor(ratio));
if (k == 0)
return 1;
return k;
}
public static Bitmap badgedBitmapForUri(Context context, Uri imageUri, String badge, double fillRatio, int color) throws IOException
{
badge = badge.trim();
Bitmap b = PurpleWidgetProvider.bitmapForUri(context, imageUri);
Bitmap badged = Bitmap.createBitmap(b.getWidth(), b.getHeight(), Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(badged);
Paint textPaint = new Paint();
textPaint.setAntiAlias(true);
textPaint.setColor(color);
textPaint.setTextSize(50);
textPaint.setTextAlign(Paint.Align.CENTER);
Rect bounds = new Rect();
if (badge.length() > 0)
{
textPaint.getTextBounds(badge, 0, badge.length(), bounds);
while (bounds.width() < (b.getWidth() * fillRatio) && bounds.height() < (b.getHeight() * fillRatio))
{
textPaint.setTextSize(textPaint.getTextSize() + 1);
textPaint.getTextBounds(badge, 0, badge.length(), bounds);
}
while (bounds.width() > (b.getWidth() * fillRatio) || bounds.height() > (b.getHeight() * fillRatio))
{
textPaint.setTextSize(textPaint.getTextSize() - 1);
textPaint.getTextBounds(badge, 0, badge.length(), bounds);
}
}
c.drawBitmap(b, 0, 0, textPaint);
if (badge.length() > 0)
c.drawText(badge, b.getWidth() / 2, (b.getHeight() / 2) + (bounds.height() / 2), textPaint);
return badged;
}
public static Bitmap bitmapForText(Context context, String text, int width, int height, String color)
{
return PurpleWidgetProvider.bitmapForText(context, text, width, height, color, false, true);
}
public static Bitmap bitmapForText(Context context, String text, int width, int height, String color, boolean verticalCenter, boolean horizontalCenter)
{
text = text.trim();
if (text.length() == 0)
return null;
DisplayMetrics metrics = context.getResources().getDisplayMetrics();
float floatWidth = width * metrics.density;
float floatHeight = height * metrics.density;
width = (int) floatWidth;
height = (int) floatHeight;
if (width < 1 || height < 1)
return null;
Bitmap b = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);
Paint textPaint = new Paint();
textPaint.setAntiAlias(true);
textPaint.setColor(Color.parseColor(color));
textPaint.setTextSize(128);
textPaint.setTextAlign(Paint.Align.CENTER);
Rect bounds = new Rect();
textPaint.getTextBounds(text, 0, text.length(), bounds);
float drawHeight = height;
while (bounds.width() < b.getWidth() && bounds.height() < drawHeight)
{
textPaint.setTextSize(textPaint.getTextSize() + 1);
textPaint.getTextBounds(text, 0, text.length(), bounds);
if (verticalCenter == false)
drawHeight = height - textPaint.descent();
}
while ((bounds.width() > b.getWidth() || bounds.height() > drawHeight) && textPaint.getTextSize() > 0)
{
textPaint.setTextSize(textPaint.getTextSize() - 1);
textPaint.getTextBounds(text, 0, text.length(), bounds);
if (verticalCenter == false)
drawHeight = height - textPaint.descent();
}
if (verticalCenter == false)
c.drawText(text, b.getWidth() / 2, (b.getHeight() / 2) + (bounds.height() / 2) - (textPaint.descent() / 2), textPaint);
else
c.drawText(text, b.getWidth() / 2, (b.getHeight() / 2) + (bounds.height() / 2), textPaint);
return b;
}
}